/*
 * Copyright 2015 泛泛o0之辈
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.jfast.framework.web.api;

import cn.jfast.framework.base.prop.CoreConsts;
import cn.jfast.framework.base.util.Assert;
import cn.jfast.framework.upload.MultiPartRequest;
import cn.jfast.framework.upload.FileRequestResolver;
import cn.jfast.framework.upload.UploadFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * Api 综合请求对象
 */
public class HttpRequest extends HttpServletRequestWrapper {

    /** HttpServletRequest请求 */
    private HttpServletRequest request;
    /** form-data 请求 */
    private MultiPartRequest fileParameterRequest;
    /** PUT请求参数 */
    private Map<String,String[]> putParameterMap = new HashMap<String,String[]>();
    /** 文件上传解析器 */
    private FileRequestResolver resolver;

    public HttpRequest(HttpServletRequest request) throws IOException {
        super(request);
        this.request = request;
        this.request.setCharacterEncoding(CoreConsts.encoding);   
        if(request.getMethod().equals("POST")){
        	resolver = new FileRequestResolver();
            fileParameterRequest = resolver.resolveMultipart(this.request);
        } else if(request.getMethod().equals("PUT")){
        	generatePutParameters();
        }
    }

    private void generatePutParameters() throws IOException {
    	if(request.getMethod().equals("PUT")){
    		putParameterMap.putAll(request.getParameterMap());
    		resolver = new FileRequestResolver();
            fileParameterRequest = resolver.resolveMultipart(this.request);
        	BufferedReader in = new BufferedReader(new InputStreamReader(this.request.getInputStream()));  
        	String line;  
            if((line = in.readLine()) != null){
            	String[] paramKv = line.split("&");
            	String[] kv;
            	for(String param:paramKv){
            		kv = param.split("=");
            		if(putParameterMap.containsKey(kv[0])) {
            			String[] nowArray = putParameterMap.get(kv[0]);
            			if(kv.length != 1){
            				String[] newArray = Arrays.copyOf(nowArray,nowArray.length+1);
            				newArray[nowArray.length] = URLDecoder.decode(kv[1],CoreConsts.encoding);
            				putParameterMap.put(kv[0], newArray);
            			}
            		} else {
            			if(kv.length == 1)
            				putParameterMap.put(kv[0], new String[]{""});
            			else
            				putParameterMap.put(kv[0], new String[]{URLDecoder.decode(kv[1],CoreConsts.encoding)});
            		}
            	}
            }  	
        }
	}

	/**
     * 获得HttpServletRequest请求
     * @return
     */
    public HttpServletRequest getRequest() {
        return request;
    }

    /**
     * 获得指定名称的上传文件
     * @param fieldName
     * @return
     */
    public List<UploadFile> getUploadFile(String fieldName) {
        if (FileRequestResolver.isMultipart(request))
            return this.fileParameterRequest.getFileMap().get(fieldName);
        else
            return null;
    }

    /**
     * 获得指定名称的参数值
     * @param fieldName
     * @return
     */
    public String getParameter(String fieldName) {
        if (FileRequestResolver.isMultipart(request)) {
        	String value = this.fileParameterRequest.getAttr(fieldName);
        	if(null == value)
        		value = request.getParameter(fieldName);
            return value;
        } else if(request.getMethod().equals("PUT")){
        	if(null == putParameterMap.get(fieldName))
        		return null;
        	Assert.isTrue(putParameterMap.get(fieldName).length==1, "参数"+fieldName+"个数错误");
            return putParameterMap.get(fieldName)[0];
        } else {
        	return request.getParameter(fieldName);
        }
    }

    /**
     * 获得数组型参数
     * @param fieldName
     * @return
     */
    public String[] getParameters(String fieldName) {
        if (FileRequestResolver.isMultipart(request)){
        	 if(null != this.fileParameterRequest.getAttrMap() && null != this.fileParameterRequest.getAttrMap().get(fieldName))
        		 return this.fileParameterRequest.getAttrMap().get(fieldName).toArray(new String[]{});
        	 else
        		 return request.getParameterValues(fieldName);
        } else if(request.getMethod().equals("PUT")){
        	 return putParameterMap.get(fieldName);
        } else {
            return request.getParameterValues(fieldName);
        }
    }

    /**
     * 获得上传文件的Map链
     * @return
     */
    public Map<String, List<UploadFile>> getFileMap() {
        return this.fileParameterRequest.getFileMap();
    }

    /**
     * 获得请求域所有参数名
     * @return
     */
    public Enumeration<String> getParameterNames() {
        if (FileRequestResolver.isMultipart(request))
            return this.fileParameterRequest.getAttrNames();
        else
            return this.request.getParameterNames();
    }

}
